package core;

public final class Geom {

	public static int calculaX(int x1, int x2, int y1, int y2, int novoY) {
		float a = getCoefAngular(x1, y1, x2, y2);
		float b = getCoefLinear(x1, y1, x2, y2);
		float x = ((float) (novoY - b)) / a;

		return (int) x;
	}

	public static int calculaY(int x1, int x2, int y1, int y2, int novoX) {
		float a = getCoefAngular(x1, y1, x2, y2);
		float b = getCoefLinear(x1, y1, x2, y2);
		float y = a * ((float) novoX) + b;

		return (int) y;
	}
	
	public static float getCoefAngular(int x1, int y1, int x2, int y2) {
		return (float) (y2 - y1) / (float) (x2 - x1);
	}
	
	public static float getCoefLinear(int x1, int y1, int x2, int y2) {
		
		if(x1 == 0) {
			return (float) y1;
		}
		
		float fx1 = (float) x1;
		float fy1 = (float) y1;
		float fx2 = (float) x2;
		float fy2 = (float) y2;
		return (fy2 - fy1*fx2/fx1)/(1 - fx2/fx1);
	}
	
	public static Point3D intersection(Point3D l1p1, Point3D l1p2, Point3D l2p1, Point3D l2p2) {
	
		Point3D point = new Point3D(0, 0);
		
		float a1 = getCoefAngular(l1p1.getX(), l1p1.getY(), l1p2.getX(), l1p2.getY());
		float a2 = getCoefAngular(l2p1.getX(), l2p1.getY(), l2p2.getX(), l2p2.getY());
		float b1 = getCoefLinear(l1p1.getX(), l1p1.getY(), l1p2.getX(), l1p2.getY());
		float b2 = getCoefLinear(l2p1.getX(), l2p1.getY(), l2p2.getX(), l2p2.getY());
		
		if(a1 == a2) {
			return null;
		}
		
		int xIntersection = (int)((b1-b2)/(a2-a1));
		int yIntersection = (int)((b2 -(b1*a2)/a1)/(1-a2/a1));
		
		point.setX(xIntersection);
		point.setY(yIntersection);
		
		return point;
	}
	
	public static Point3D verticalLineIntersection(Point3D p1, Point3D p2, int x) {
		Point3D point = new Point3D(x, 0);
		
		if(p1.getY() == p2.getY()) {
			//teta = 0
			point.setY(p1.getY());
		}else {
			point.setY(calculaY(p1.getX(), p2.getX(), p1.getY(), p2.getY(), x));
		}
		
		return point;
	}
	
	public static Point3D horizontallLineIntersection(Point3D p1, Point3D p2, int y) {
		Point3D point = new Point3D(0, y);
		
		if(p1.getX() == p2.getX()) {
			point.setX(p1.getX());
		}else {
			point.setX(calculaX(p1.getX(), p2.getX(), p1.getY(), p2.getY(), y));
		}
		
		return point;
	}
	
	public static boolean lineIntersects(Point3D p1, Point3D p2, Point3D p, double error) {
		return lineIntersects(
				p1.getX(), p1.getY(), p2.getX(), p2.getY(), p.getX(), p.getY(), error);
	}
	
	public static boolean lineIntersects(int x1, int y1, int x2, int y2, int x, int y, double error) {
		
		if(Math.abs(x1-x2) < Math.abs(y1-y2)) {
			return lineIntersects(y1, x1, y2, x2, y, x, error);
		}
		
		double xMax = Math.max(x1, x2);
		double xMin = Math.min(x1, x2);
		
		double coefAng = (double)(y2 - y1)/(double)(x2 - x1);
		double coefLin = ((double)y1) - coefAng*((double)x1);
		
		if(x >= xMin - error && x <= xMax + error) {
			double py   = coefAng * (double)x + coefLin;
			double yMax = py + error; 
			double yMin = py - error;
			
			if(y >= yMin && y <= yMax){
				return true;
			}
		}

		return false;
	}

	public static void main(String args[]) {
		Point3D p1 = new Point3D(0, 2);
		Point3D p2 = new Point3D(8, 2);
		
		Point3D intersection = Geom.verticalLineIntersection(p1, p2, 4);
		
		System.out.printf("(x=%d, y=%d)", intersection.getX(), intersection.getY());
	}
}
